﻿
using Patterns4Net.ArchitectureExplorer.Diagram.Relations;
using Patterns4Net.ArchitectureExplorer.Diagram.Services.Relations;

namespace Patterns4Net.ArchitectureExplorer.Diagram.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;

    /// <summary>
    /// An interface for <see cref="DiagramUpdaterExportAttribute"/>.
    /// Interface for export attributes is required from MEF.
    /// </summary>
    public interface IDiagramUpdaterMetadata
    {
        /// <summary>
        /// Specifies the order in which the updaters will be executed. 
        /// Higher number - later executed.
        /// </summary>
        int Order { get; }
    }

    /// <summary>
    /// Defines an export for for <see cref="IDiagramUpdater"/> services. 
    /// These services can define their order using the <see cref="Order"/> property of 
    /// this attribute.
    /// </summary>
    /// <remarks>
    /// <para>
    /// The order of built in updates is following:
    ///     <list type="bullet">
    ///         <item>
    ///             <term><see cref="PatternUpdater"/></term>
    ///             <description>Adds patterns to types and method. Order = 0.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="PatternRolesProvider"/></term>
    ///             <description>Adds relations based on patterns roles. Order = 1.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="InheritanceProvider"/></term>
    ///             <description>Adds <see cref="Inheritance"/> relations. Order = 10.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="CompositionProvider"/></term>
    ///             <description>Adds <see cref="Composition"/> relations. Order = 20.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="AggregationProvider"/></term>
    ///             <description>Adds <see cref="Aggregation"/> relations. Order = 30.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="AssociationProvider"/></term>
    ///             <description>Adds <see cref="Association"/> relations. Order = 40.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="UsesProvider"/></term>
    ///             <description>Adds <see cref="Uses"/> relations, 
    ///             which are sometimes not added when other relations were found before. Order = 50.</description>
    ///         </item>
    ///         <item>
    ///             <term><see cref="MergeRelations"/></term>
    ///             <description>Merges relations that can be merged into one. Order = 1000.</description>
    ///         </item>
    ///     </list>
    /// </para>
    /// </remarks>
    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class DiagramUpdaterExportAttribute : ExportAttribute, IDiagramUpdaterMetadata
    {
        public DiagramUpdaterExportAttribute()
            : base(typeof(IDiagramUpdater))
        {
            this.Order = 0;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DiagramUpdaterExportAttribute"/> class.
        /// A constructor required by MEF.
        /// </summary>
        public DiagramUpdaterExportAttribute(IDictionary<string, object> data)
        {
            object priority;
            if (data.TryGetValue("Priority", out priority) && priority is int)
            {
                this.Order = (int)priority;
            }
        }

        /// <summary>
        /// Specifies the order in which the updaters will be executed.
        /// Higher number - later executed.
        /// </summary>
        public int Order { get; set; }
    }
}
